package zookeeper.demo01;

import org.apache.zookeeper.*;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.data.Stat;
import org.junit.jupiter.api.Test;

import java.io.IOException;

public class Watch {
    
    private static final int SESSION_TIMEOUT = 2000;

    @Test
    public void watchOperation() throws IOException, KeeperException, InterruptedException{
        //打开连接
        final ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", SESSION_TIMEOUT, new Watcher() {
            
            public void process(WatchedEvent event) {
                System.out.println("1-type:"+event.getType()+",path:"+event.getPath()+",state:"+event.getState());
            }
        });
        
        if(zk.exists("/zkdemo_watch/child", true)!=null){
            //删除子节点
            zk.delete("/zkdemo_watch/child", -1);
        }
        if(zk.exists("/zkdemo_watch", true)!=null){
            //删除父节点
            zk.delete("/zkdemo_watch", -1);
        }
        
        //创建父节点
        zk.create("/zkdemo_watch", "watch parent".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        addWatch(zk,"/zkdemo_watch",1);
        
        //更新父节点
        zk.setData("/zkdemo_watch", "watch parent update".getBytes(), -1, new AsyncCallback.StatCallback() {
            
            public void processResult(int rc, String path, Object ctx, Stat stat) {
                System.out.println("rc:"+rc+",path:"+path+",ctx:"+ctx+",stat:"+stat);
                try {
                    addWatch(zk,"/zkdemo_watch",2);
                } catch (KeeperException e) {
                    // lichao Auto-generated catch block
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // lichao Auto-generated catch block
                    e.printStackTrace();
                }
            }
        },null);
        zk.setData("/zkdemo_watch", "watch parent update2".getBytes(), -1);
        //addWatchFlag(zk,"/zkdemo_watch",2);
        //更新父节点acl
        //zk.setACL("/zkdemo_watch", Ids.OPEN_ACL_UNSAFE, -1);
        //addWatchFlag(zk,"/zkdemo_watch",3);
        
        //创建子节点
        zk.create("/zkdemo_watch/child", "watch child".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        addWatch(zk,"/zkdemo_watch/child",4);
        
        //更新子节点
        zk.setData("/zkdemo_watch/child", "watch parent update".getBytes(), -1);
        zk.setData("/zkdemo_watch/child", "watch parent update2".getBytes(), -1);
        //addWatchFlag(zk,"/zkdemo_watch/child",5);
        //更新子节点acl
        //zk.setACL("/zkdemo_watch/child", Ids.READ_ACL_UNSAFE, -1);
        //addWatchFlag(zk,"/zkdemo_watch/child",6);
        
        //删除子节点
        zk.delete("/zkdemo_watch/child", -1);
        //删除父节点
        zk.delete("/zkdemo_watch", -1);
    }

    private void addWatch(ZooKeeper zk, final String path, final int flag) throws KeeperException, InterruptedException {
        //获取数据并设置watch
        zk.getData(path, new Watcher() {
            
            public void process(WatchedEvent event) {
                System.out.println("---------"+flag+"---------");
                System.out.println(path+"-getData-type:"+event.getType()+",path:"+event.getPath()+",state:"+event.getState());
                System.out.println("---------"+flag+"---------");
            }
        }, null);
        //查看节点状态并设置watch
        zk.exists(path, new Watcher() {
            
            public void process(WatchedEvent event) {
                System.out.println("---------"+flag+"---------");
                System.out.println(path+"-exists-type:"+event.getType()+",path:"+event.getPath()+",state:"+event.getState());
                System.out.println("---------"+flag+"---------");
            }
        });
        //获取子节点并设置watch
        zk.getChildren(path, new Watcher() {
            
            public void process(WatchedEvent event) {
                System.out.println("---------"+flag+"---------");
                System.out.println(path+"-getChildren-type:"+event.getType()+",path:"+event.getPath()+",state:"+event.getState());
                System.out.println("---------"+flag+"---------");
            }
        });
    }
    
    private void addWatchFlag(ZooKeeper zk, final String path, final int flag) throws KeeperException, InterruptedException {
        //获取数据并设置watch
        zk.getData(path, true, null);
        //查看节点状态并设置watch
        zk.exists(path, true);
        //获取子节点并设置watch
        zk.getChildren(path, true);
    }
}
